#pragma once
#include <QObject>
#include <QString>
#include <QMutex>
#include <QFile>
#include <QTimer>
#include <QDate>
#include <QVector>
#include <QSharedPointer>

enum LogLevel{
    LOG_INFO,
    LOG_WARNING,
    LOG_ERROR,
    LOG_FATAL,
};

class LogObject
{
public:    
    int module;
    LogLevel level;
    QDateTime time;
    QString message;
};
typedef QSharedPointer<LogObject> LogObjectPtr;

enum{
    Module_General,    
};

class LogManager : public QObject
{
    Q_OBJECT

public:
    static LogManager *instance();

    void init(QString outPath);
    void deinit();
    void registModule(int type, QString name);

    void setLogLevel(LogLevel level);
    void log(int module, LogLevel level, const char *format, ...);        

signals:
    void sigLog(LogObjectPtr log);

protected slots:
    void onTimeOut();

protected:
    struct ModuleInfo
    {
        QString name;
        QFile file;
        QStringList logBuffer;        
    };
    typedef QSharedPointer<ModuleInfo> ModulePtr;

    LogManager();
    ~LogManager();
    void createFile();
    void flush();

    QString m_outPath;
    QMutex m_mutex;
    QTimer m_timer;
    QDateTime m_curTime;
    LogLevel m_logLevel;
    QVector<ModulePtr> m_logModule;
    bool m_init;
};

#define LogInfo(...) LogManager::instance()->log(Module_General,LOG_INFO,__VA_ARGS__)
#define LogWarning(...) LogManager::instance()->log(Module_General,LOG_WARNING,__VA_ARGS__)
#define LogError(...) LogManager::instance()->log(Module_General,LOG_ERROR,__VA_ARGS__)
#define LogFatal(...) LogManager::instance()->log(Module_General,LOG_FATAL,__VA_ARGS__)